{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.2. Creating NumPy Arrays"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2.1 Using Array Method"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "numpy.ndarray"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "nums_list = [10,12,14,16,20]\n",
    "nums_array = np.array(nums_list)\n",
    "type(nums_array)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3, 3)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "row1 = [10,12,13]\n",
    "row2 = [45,32,16]\n",
    "row3 = [45,32,16]\n",
    "\n",
    "nums_2d = np.array([row1, row2, row3])\n",
    "nums_2d.shape                 "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2.2. Using Arange Method"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 5  6  7  8  9 10]\n"
     ]
    }
   ],
   "source": [
    "nums_arr = np.arange(5,11)\n",
    "print(nums_arr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 5  7  9 11]\n"
     ]
    }
   ],
   "source": [
    "nums_arr = np.arange(5,12,2)\n",
    "print(nums_arr)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2.3. Using Ones Method"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1. 1. 1. 1. 1. 1.]\n"
     ]
    }
   ],
   "source": [
    "ones_array = np.ones(6)\n",
    "print(ones_array)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1. 1. 1. 1.]\n",
      " [1. 1. 1. 1.]\n",
      " [1. 1. 1. 1.]\n",
      " [1. 1. 1. 1.]\n",
      " [1. 1. 1. 1.]\n",
      " [1. 1. 1. 1.]]\n"
     ]
    }
   ],
   "source": [
    "ones_array = np.ones((6,4))\n",
    "print(ones_array)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2.4. Using Zeros Method"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0. 0. 0. 0. 0. 0.]\n"
     ]
    }
   ],
   "source": [
    "zeros_array = np.zeros(6)\n",
    "print(zeros_array)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0. 0. 0. 0.]\n",
      " [0. 0. 0. 0.]\n",
      " [0. 0. 0. 0.]\n",
      " [0. 0. 0. 0.]\n",
      " [0. 0. 0. 0.]\n",
      " [0. 0. 0. 0.]]\n"
     ]
    }
   ],
   "source": [
    "zeros_array = np.zeros((6,4))\n",
    "print(zeros_array)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2.5. Using Eyes Method"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1. 0. 0. 0. 0.]\n",
      " [0. 1. 0. 0. 0.]\n",
      " [0. 0. 1. 0. 0.]\n",
      " [0. 0. 0. 1. 0.]\n",
      " [0. 0. 0. 0. 1.]]\n"
     ]
    }
   ],
   "source": [
    "eyes_array = np.eye(5)\n",
    "print(eyes_array)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2.6. Using Random Method"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0.36728531 0.25376281 0.05039624 0.96432236 0.08579293]\n",
      " [0.29194804 0.93016399 0.88781312 0.50209692 0.63069239]\n",
      " [0.99952044 0.44384871 0.46041845 0.10246553 0.53461098]\n",
      " [0.75817916 0.36505441 0.01683344 0.9887365  0.21490949]]\n"
     ]
    }
   ],
   "source": [
    "uniform_random = np.random.rand(4, 5)\n",
    "print(uniform_random)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0.36728531 0.25376281 0.05039624 0.96432236 0.08579293]\n",
      " [0.29194804 0.93016399 0.88781312 0.50209692 0.63069239]\n",
      " [0.99952044 0.44384871 0.46041845 0.10246553 0.53461098]\n",
      " [0.75817916 0.36505441 0.01683344 0.9887365  0.21490949]]\n"
     ]
    }
   ],
   "source": [
    "normal_random = np.random.randn(4, 5)\n",
    "print(uniform_random)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[25 49 21 35 17]\n"
     ]
    }
   ],
   "source": [
    "integer_random = np.random.randint(10, 50, 5)\n",
    "print(integer_random)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.3. Reshaping a Numpy Array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0.37576967 0.5425328  0.56087883 0.35265748 0.19677258 0.65107479\n",
      "  0.63287089 0.70649913]\n",
      " [0.47830882 0.3570451  0.82151482 0.09622735 0.1269332  0.65866216\n",
      "  0.31875221 0.91781242]\n",
      " [0.89785438 0.47306848 0.58350797 0.4604004  0.62352155 0.88064432\n",
      "  0.0859386  0.51918485]]\n"
     ]
    }
   ],
   "source": [
    "uniform_random = np.random.rand(4, 6)\n",
    "uniform_random = uniform_random.reshape(3, 8)\n",
    "print(uniform_random)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.4. Array Indexing and Slicing in NumPy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 1  2  3  4  5  6  7  8  9 10]\n"
     ]
    }
   ],
   "source": [
    "s = np.arange(1,11)\n",
    "print(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n"
     ]
    }
   ],
   "source": [
    "print(s[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2 3 4 5 6 7 8 9]\n"
     ]
    }
   ],
   "source": [
    "print(s[1:9])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3 4 5]\n",
      "[ 6  7  8  9 10]\n"
     ]
    }
   ],
   "source": [
    "print(s[:5])\n",
    "print(s[5:])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[10 12 13]\n",
      " [45 32 16]]\n"
     ]
    }
   ],
   "source": [
    "row1 = [10,12,13]\n",
    "row2 = [45,32,16]\n",
    "row3 = [45,32,16]\n",
    "\n",
    "nums_2d = np.array([row1, row2, row3])\n",
    "print(nums_2d[:2,:]) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[10 12]\n",
      " [45 32]\n",
      " [45 32]]\n"
     ]
    }
   ],
   "source": [
    "row1 = [10,12,13]\n",
    "row2 = [45,32,16]\n",
    "row3 = [45,32,16]\n",
    "\n",
    "nums_2d = np.array([row1, row2, row3])\n",
    "print(nums_2d[:,:2]) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[32 16]\n",
      " [32 16]]\n"
     ]
    }
   ],
   "source": [
    "row1 = [10,12,13]\n",
    "row2 = [45,32,16]\n",
    "row3 = [45,32,16]\n",
    "\n",
    "nums_2d = np.array([row1, row2, row3])\n",
    "print(nums_2d[1:,1:]) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.5. NumPy for Arithmetic Operations"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.5.1. Finding Square Root"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3.16227766 4.47213595 5.47722558 6.32455532 7.07106781]\n"
     ]
    }
   ],
   "source": [
    "nums = [10,20,30,40,50]\n",
    "np_sqr = np.sqrt(nums)\n",
    "print(np_sqr)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.5.2. Finding Logs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2.30258509 2.99573227 3.40119738 3.68887945 3.91202301]\n"
     ]
    }
   ],
   "source": [
    "nums = [10,20,30,40,50]\n",
    "np_log = np.log(nums)\n",
    "print(np_log )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.5.3. Finding Exponents"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2.20264658e+04 4.85165195e+08 1.06864746e+13 2.35385267e+17\n",
      " 5.18470553e+21]\n"
     ]
    }
   ],
   "source": [
    "nums = [10,20,30,40,50]\n",
    "np_exp = np.exp(nums)\n",
    "print(np_exp)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.5.4. Finding Sine and Cosine"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-0.54402111  0.91294525 -0.98803162  0.74511316 -0.26237485]\n",
      "[-0.83907153  0.40808206  0.15425145 -0.66693806  0.96496603]\n"
     ]
    }
   ],
   "source": [
    "nums = [10,20,30,40,50]\n",
    "np_sine = np.sin(nums)\n",
    "print(np_sine)\n",
    "\n",
    "nums = [10,20,30,40,50]\n",
    "np_cos = np.cos(nums)\n",
    "print(np_cos)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.6. NumPy for Linear Algebra Operations"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.6.1. Dot Product of Matrices"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1.43837722 -4.74991285  1.42127048 -0.41569506]\n",
      " [-1.64613809  5.79380984 -1.33542482  1.53201023]\n",
      " [-1.31518878  0.72397674 -2.01300047  0.61651047]\n",
      " [-1.36765444  3.83694475 -0.56382045  0.21757162]]\n"
     ]
    }
   ],
   "source": [
    "A = np.random.randn(4,5)\n",
    "\n",
    "B = np.random.randn(5,4)\n",
    "\n",
    "Z =  np.dot(A,B)\n",
    "\n",
    "print(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.6.2. Element-wise Matrix Multiplication"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 100  144  169]\n",
      " [2025 1024  256]\n",
      " [2025 1024  256]]\n"
     ]
    }
   ],
   "source": [
    "row1 = [10,12,13]\n",
    "row2 = [45,32,16]\n",
    "row3 = [45,32,16]\n",
    "\n",
    "nums_2d = np.array([row1, row2, row3])\n",
    "multiply = np.multiply(nums_2d, nums_2d)\n",
    "print(multiply)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.6.3. Finding Matrix Inverse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 3.15251974e+15 -6.30503948e+15  3.15251974e+15]\n",
      " [-6.30503948e+15  1.26100790e+16 -6.30503948e+15]\n",
      " [ 3.15251974e+15 -6.30503948e+15  3.15251974e+15]]\n"
     ]
    }
   ],
   "source": [
    "row1 = [1,2,3]\n",
    "row2 = [4,5,6]\n",
    "row3 = [7,8,9]\n",
    "\n",
    "nums_2d = np.array([row1, row2, row3])\n",
    "\n",
    "inverse = np.linalg.inv(nums_2d)\n",
    "print(inverse)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.6.4. Finding Matrix Determinant"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-9.51619735392994e-16\n"
     ]
    }
   ],
   "source": [
    "row1 = [1,2,3]\n",
    "row2 = [4,5,6]\n",
    "row3 = [7,8,9]\n",
    "\n",
    "nums_2d = np.array([row1, row2, row3])\n",
    "\n",
    "determinant = np.linalg.det(nums_2d)\n",
    "print(determinant)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.6.5. Finding Matrix Trace"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "15\n"
     ]
    }
   ],
   "source": [
    "row1 = [1,2,3]\n",
    "row2 = [4,5,6]\n",
    "row3 = [7,8,9]\n",
    "\n",
    "nums_2d = np.array([row1, row2, row3])\n",
    "\n",
    "trace = np.trace(nums_2d)\n",
    "print(trace)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Excersise 3.1\n",
    "\n",
    "**Question 1:**\n",
    "\n",
    "Which NumPy function is used for element-wise multiplication of two matrices?\n",
    "\n",
    "A- np.dot(matrix1, matrix2) \n",
    "\n",
    "B- np.multiply(matrix1, matrix2)\n",
    "\n",
    "C- np.elementwise(matrix1, matrix2) \n",
    "\n",
    "D- None of the above\n",
    "\n",
    "Answer: B\n",
    "\n",
    "\n",
    "**Question 2:**\n",
    "\n",
    "To generate an identity matrix of 4 rows and 4 columns, which of the following functions can be used?\n",
    "\n",
    "A- np.identity(4,4)\n",
    "\n",
    "B- np.id(4,4)\n",
    "\n",
    "C- np.eye(4,4) \n",
    "\n",
    "D- All of the above\n",
    "\n",
    "Answer: C\n",
    "\n",
    "\n",
    "**Question 3:**\n",
    "\n",
    "How to create the array of numbers 4,7,10,13,16 with NumPy: \n",
    "\n",
    "A- np.arange(3, 16, 3)\n",
    "\n",
    "B- np.arange(4, 16, 3)\n",
    "\n",
    "C- np.arange(4, 15,3) \n",
    "\n",
    "D- None of the above\n",
    "\n",
    "Answer: D"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Excersise 3.2\n",
    "\n",
    "Create a random NumPy array of 5 rows and 4 columns. Using array indexing and slicing, display the items from row 3 to end and column 2 to end.\n",
    "\n",
    "**Solution:**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0.72452886 0.72041584 0.04077573 0.06427304 0.50293137]\n",
      " [0.80496061 0.30012932 0.18061954 0.06908943 0.68391114]\n",
      " [0.4764706  0.94582802 0.36850443 0.83954099 0.30519222]\n",
      " [0.88190253 0.16131323 0.68356525 0.68893982 0.65417021]]\n",
      "Result\n",
      "[[0.83954099 0.30519222]\n",
      " [0.68893982 0.65417021]]\n"
     ]
    }
   ],
   "source": [
    "uniform_random = np.random.rand(4, 5)\n",
    "print(uniform_random)\n",
    "print(\"Result\")\n",
    "print(uniform_random[2:,3:])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
